package org.oos.lists;

import java.util.AbstractList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import org.oos.OOS4Java;
import org.oos.atom.entries.ContactEntry;
import org.oos.dao.lists.RestoredDynamicList;
import org.oos.model.Contact;

public class ContactList extends AbstractList<Contact> implements RestorableList<ContactEntry> {

	private OOS4Java oos4Java;
	private List<ContactEntry> list;
	private Map<ContactEntry, Contact> cache = new WeakHashMap<ContactEntry, Contact>();

	public ContactList(OOS4Java oos4Java, List<ContactEntry> list) {
		this.oos4Java = oos4Java;
		this.list = list;
	}

	@Override
	public Contact get(int location) {
		ContactEntry entry = list.get(location);
		Contact result;
		if (cache.containsKey(entry)) {
			result = cache.get(entry);
		} else {
			result = new Contact(oos4Java, list.get(location));
			cache.put(entry, result);
		}
		return result;
	}
	
	public Contact find(String userSlug, String contactSlug) {
		for (Contact contact : this) {
			if (contact.getContactSlug().equals(contactSlug)
					&& contact.getUserSlug().equals(userSlug)) {
				return contact;
			}
		}
		return null;
	}

	@Override
	public int size() {
		return list.size();
	}

	@Override
	public boolean add(Contact contact) {
		oos4Java.resetUser(contact.getContactSlug());
		return list.add((ContactEntry)contact.getEntry());
	}

	public Contact update(Contact contact) {
		oos4Java.resetUser(contact.getContactSlug());
		int index = list.indexOf((ContactEntry)contact.getEntry());
		return this.set(index, contact);
	}

	@Override
	public Contact set(int index, Contact contact) {
		oos4Java.resetUser(contact.getContactSlug());
		ContactEntry entry = list.set(index, contact.getEntry());
		return new Contact(oos4Java, entry);
	}

	@Override
	public Contact remove(int index) {
		ContactEntry entry = list.remove(index);
		oos4Java.resetUser(entry.getSlug());
		return new Contact(oos4Java, entry);
	}

	@Override
	public boolean remove(Object o) {
		if (o instanceof Contact) {
			Contact contact = (Contact) o;
			oos4Java.resetUser(contact.getContactSlug());
			return list.remove(contact.getEntry());
		} else {
			return false;
		}
	}
	
	@Override
	public void clear() {
		cache.clear();
		super.clear();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public void sort(Comparator<ContactEntry> comparator) {
		if (isRestored()) {
			((RestoredDynamicList) this.list).sort(comparator);
		}
	}

	@Override
	public void sort() {
		sort(new Comparator<ContactEntry>() {
			@Override
			public int compare(ContactEntry c1, ContactEntry c2) {
				String name1 = c1.getTitle().getValue().toLowerCase();
				String name2 = c2.getTitle().getValue().toLowerCase();
				return name1.compareTo(name2);
			}
		});
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean isRestored() {
		return this.list instanceof RestoredDynamicList;
	}
}
